package cn.yshujia.repository;

import cn.yshujia.domain.entity.Router;
import cn.yshujia.domain.vo.RouterVO;
import cn.yshujia.mapper.RouterMapper;
import cn.yshujia.transform.RouterTransform;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Repository;
import org.springframework.util.ObjectUtils;

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Repository
public class RouterRepository {
	
	@Resource
	RedisTemplate<String, RouterVO> redis;
	
	@Resource
	RouterMapper routerMapper;
	
	@Resource
	RoleRepository roleRepository;
	
	public static final String LIST = "router:roleId:";
	
	public static final Duration DURATION = Duration.ofDays(3L);
	
	public List<RouterVO> getRoutersByRoleId(Long roleId) {
		List<RouterVO> list = redis.opsForList().range(LIST + roleId, 0L, -1L);
		if (!ObjectUtils.isEmpty(list)) {
			return list;
		}
		List<Router> sql = routerMapper.selectList(new LambdaQueryWrapper<Router>()
				.eq(Router::getLevel, 1)
				.eq(Router::getStatus, true)
				.ge(Router::getRoleId, roleId)
				.orderByAsc(Router::getPriority));
		if (ObjectUtils.isEmpty(sql)) {
			return list;
		}
		list = new ArrayList<>();
		for (Router router : sql) {
			RouterVO routerVO = RouterTransform.entity2VO(router);
			// 封装子路由
			List<Router> children = routerMapper.selectList(new LambdaQueryWrapper<Router>()
					.eq(Router::getParentId, router.getId())
					.eq(Router::getStatus, true)
					.ge(Router::getRoleId, roleId)
					.orderByAsc(Router::getPriority));
			List<RouterVO> childrenVOList = new ArrayList<>();
			if (!ObjectUtils.isEmpty(children)) {
				for (Router child : children) {
					RouterVO childVO = RouterTransform.entity2VO(child);
					childrenVOList.add(childVO);
				}
				routerVO.setChildren(childrenVOList);
			}
			list.add(routerVO);
		}
		set(list, LIST + roleId);
		return list;
	}
	
	public List<RouterVO> createVOList(List<Router> routers) {
		List<RouterVO> list = new ArrayList<>();
		if (ObjectUtils.isEmpty(routers)) {
			return list;
		}
		
		for (Router router : routers) {
			RouterVO vo = RouterTransform.entity2VO(router);
			vo.setRole(roleRepository.getRole(vo.getRoleId()));
			list.add(vo);
		}
		return list;
	}
	
	@Async ("Task")
	public void set(List<RouterVO> value, String key) {
		redis.opsForList().rightPushAll(key, value);
		redis.opsForList().getOperations().expire(key, DURATION);
	}
	
	@Async ("Task")
	public void del() {
		Set<String> keys = redis.keys(LIST + "*");
		redis.delete(keys);
	}
}